/**
  ******************************************************************************
  * @file    STM32F0xx_IAP/src/menu.c 
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    29-May-2012
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "common.h"
#include "flash_if.h"
#include "menu.h"
#include "ymodem.h"
//add by wenfeng
#include "string.h"

#define  SW_RESET()        NVIC_SystemReset() 

/** @addtogroup STM32F0xx_IAP
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
pFunction Jump_To_Application;
uint32_t JumpAddress;
extern uint32_t UserMemoryMask;
uint32_t FlashProtection = 0;
uint8_t tab_1024[1024] =
  {
    0
  };
uint8_t FileName[FILE_NAME_LENGTH];

/* Private function prototypes -----------------------------------------------*/
void SerialDownload(void);
void SerialUpload(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Download a file via serial port
  * @param  None
  * @retval None
  */
void SerialDownload(void)
{
  uint8_t Number[10] = {0};
  int32_t Size = 0;

  SerialPutString("Waiting for the file to be sent \n");
  Size = Ymodem_Receive(&tab_1024[0]);
  if (Size > 0)
  {
    SerialPutString("Programming Completed Successfully!\n Name: ");
    SerialPutString(FileName);
    Int2Str(Number, Size);
    SerialPutString("\n Size: ");
    SerialPutString(Number);
    SerialPutString(" Bytes\r\n");
    SerialPutString("-------------------\n");
		SerialPutString("reboot\n");
		delay_ms(500);
		USART_Cmd(USART1, DISABLE);
		SW_RESET();
  }
  else if (Size == -1)
  {
    SerialPutString("The image size is higher than the allowed space memory!\n");
  }
  else if (Size == -2)
  {
    SerialPutString("Verification failed!\n");
  }
  else if (Size == -3)
  {
    SerialPutString("Aborted by user.\n");
  }
  else
  {
    SerialPutString("Failed to receive the file!\n");
  }
}

/**
  * @brief  Upload a file via serial port.
  * @param  None
  * @retval None
  */
void SerialUpload(void)
{
  uint8_t status = 0 ; 

  SerialPutString("\n\n\rSelect Receive File\n\r");

  if (GetKey() == CRC16)
  {
    /* Transmit the flash image through ymodem protocol */
    status = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (const uint8_t*)"UploadedFlashImage.bin", USER_FLASH_SIZE);

    if (status != 0) 
    {
      SerialPutString("\n\rError Occurred while Transmitting File\n\r");
    }
    else
    {
      SerialPutString("\n\rFile uploaded successfully \n\r");
    }
  }
}


void delay_us(uint16_t time)
{    
   uint16_t i=0;  
   while(time--)
   {
      i=10;
      while(i--) ;    
   }
}

void delay_ms(uint16_t time)
{    
   uint16_t i=0;  
   while(time--)
   {
      i=12000;
      while(i--) ;    
   }
}


void Print_Reboot_Flag(void)
{
	if(RCC->CSR & ((uint32_t)1)<<31){
		SerialPutString("reboot:Low-power!\r\n");
	}else if(RCC->CSR & ((uint32_t)1)<<30){
		SerialPutString("reboot:Window watchdog!\r\n");
	}else if(RCC->CSR & ((uint32_t)1)<<29){
		SerialPutString("reboot:Independent watchdog!\r\n");
	}else if(RCC->CSR & ((uint32_t)1)<<28){
		SerialPutString("reboot:Software!\r\n");
	}else if(RCC->CSR & ((uint32_t)1)<<27){
		SerialPutString("reboot:POR/PDR!\r\n");
	}else if(RCC->CSR & ((uint32_t)1)<<26){
		SerialPutString("reboot:PIN!\r\n");
	}else if(RCC->CSR & ((uint32_t)1)<<25){
		SerialPutString("reboot:BOR!\r\n");
	}
}

void Clear_Reboot_Flag(void)
{
	RCC->CSR |= 1<<24;
}



/**
  * @brief  Display the Main Menu on HyperTerminal
  * @param  None
  * @retval None
  */
void Main_Menu(void)
{
	//add by wenfeng
	uint8_t cmd[32] = {0};
	uint32_t cmd_len;
	
  //WriteFlashOneWord(UPDATE_FLAG_ADDR, 0x01);
	//WriteFlashOneWord(UPDATE_FLAG_ADDR + 1024 , 0x02);
	//WriteFlashOneWord(UPDATE_FLAG_ADDR + 1024 + 1024 , 0x03);
	//WriteFlashOneWord(UPDATE_FLAG_ADDR + 1024 + 1024 + 1024 , 0x04);
	//WriteFlashOneWord(UPDATE_FLAG_ADDR + 1024 + 1024 + 1024 + 1024 , 0x05);
  //ReadFlash(UPDATE_FLAG_ADDR);
	//ReadFlash(UPDATE_FLAG_ADDR + 1024);
	//ReadFlash(UPDATE_FLAG_ADDR + 1024 + 1024);
	//ReadFlash(UPDATE_FLAG_ADDR + 1024 + 1024 + 1024); 
	//ReadFlash(UPDATE_FLAG_ADDR + 1024 + 1024 + 1024 + 1024); 
  /* Test if any sector of Flash memory where user application will be loaded is write protected */
  if (FLASH_If_GetWriteProtectionStatus() != 0)  
  {
    FlashProtection = 1;
  }
  else
  {
    FlashProtection = 0;
  }

  while (1)
  {

    /* Receive cmd */
		Print_Reboot_Flag();
		Clear_Reboot_Flag();
		SerialPutString("STAT=BL\n");
		memset(cmd, 0, 32);     
		
		cmd_len = GetInputString(cmd);
		if (cmd_len == strlen(GET_STATUS_CMD) && strncmp((char*)cmd, GET_STATUS_CMD, cmd_len) == 0)
		{
			SerialPutString("STAT=BL\n");
		} 
		else if (cmd_len == 1 && cmd[0] == DOWNLOAD_CMD)
		{
			TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE );//close timer
			SerialPutString("download cmd\n");
			SerialDownload();
		}
		else if (cmd_len == 1 && cmd[0] == APP_CMD)
		{
			TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE );//close timer
			SerialPutString("go to app\n");
			USART_Cmd(USART1, DISABLE);
			delay_ms(500);
      Go_To_App();
		} 
		else
		{
			SerialPutString("invalid cmd\n");
		}
		
		/*
		SerialPutString("\r\n================== Main Menu ============================\r\n\n");
    SerialPutString("  Download Image To the STM32F0xx Internal Flash ------- 1\r\n\n");
    //SerialPutString("  Upload Image From the STM32F0xx Internal Flash ------- 2\r\n\n");
		SerialPutString("  erase flash ------- 2\r\n\n");
    SerialPutString("  Execute The New Program ------------------------------ 3\r\n\n");

    if(FlashProtection != 0)
    {
      SerialPutString("  Disable the write protection ------------------------- 4\r\n\n");
    }

    SerialPutString("==========================================================\r\n\n");
		key = GetKey();
    if (key == 0x31)
    {
      // Download user application in the Flash
      SerialDownload();
    }
    else if (key == 0x32)
    {
      //Upload user application from the Flash
      //SerialUpload();
			FLASH_If_Erase(APPLICATION_ADDRESS);
    }
    else if (key == 0x33)//execute the new program
    {
			SerialPutString("  wenfengtou Jump to user application 3\r\n\n");
      //Jump to user application
      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
      Jump_To_Application = (pFunction) JumpAddress;

      // Initialize user application's Stack Pointer
      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
      
      //Jump to application
      Jump_To_Application();
    }
    else if ((key == 0x34) && (FlashProtection == 1))
    {
      //Disable the write protection 
      writeprotect = FLASH_If_DisableWriteProtection();

      switch (writeprotect)
      {
        case 0:
        {
          SerialPutString("Write Protection disabled...\r\n");
          SerialPutString("...and a System Reset will be generated to reload the new option bytes\r\n");
          
          //Launch loading new option bytes
          FLASH_OB_Launch();
          
          break;
        }
        case 1:
        {
          SerialPutString("Error: Flash write unprotection failed...\r\n");
          break;
        }
        case 2:
        {
          SerialPutString("Flash memory not write protected\r\n");
          break;
        }
        default:
        {
        }
      }
    }
    else
    {
      if (FlashProtection == 0)
      {
        SerialPutString("Invalid Number ! ==> The number should be either 1, 2 or 3\r");
      }
      else
      {
        SerialPutString("Invalid Number ! ==> The number should be either 1, 2, 3 or 4\r");
      }
    }
		*/
		
		
		
  }
}

void Go_To_App(void) 
{
		//Jump to user application
		JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
		Jump_To_Application = (pFunction) JumpAddress;

		// Initialize user application's Stack Pointer
		__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
		
		Jump_To_Application();
}


/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
